#include <linux/errno.h>
#include <linux/sched.h>

static void forget_original_parent(struct task_struct *father) {
    struct task_struct *p;

    for_each_task(p) {
        if (p->p_opptr == father) {
            if (task[1])
                p->p_opptr = task[1];
            else
                p->p_opptr = task[0];
        }
    }
}

void do_exit(long code) {
    struct task_struct *p;

fake_volatile:
    free_page_tables(current);
    forget_original_parent(current);
    current->state = TASK_ZOMBIE;
    current->exit_code = code;

    p = current->p_cptr;
    while (p != NULL) {
        current->p_cptr = p->p_osptr;
        p->p_ysptr = NULL;
        if (task[1] && task[1] != current)
            p->p_pptr = task[1];
        else
            p->p_pptr = task[0];
        p->p_osptr = p->p_pptr->p_cptr;
        p->p_osptr->p_ysptr = p;
        p->p_pptr->p_cptr = p;
        p = current->p_cptr;
    }

    schedule();

    goto fake_volatile;
}

int sys_exit(int error_code) {
    do_exit((error_code & 0xff) << 8);
}
